﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StackExchange.Redis;
using Abp.Dependency;
using System.Configuration;

namespace GN.Pay.Core.Runtime.Caching.Impl
{
    /// <summary>
    /// 
    /// </summary>
    class RedisProvider : IRedisProvider
    {
        private const string connectionKey = "Redis_Server";
        private const string databaseIdKey = "Redis_DatabaseId";

        private static ConnectionMultiplexer connectionMultiplexer = null;
        private static object connectLock = new object();
        private IDatabase database;

        /// <summary>
        /// 
        /// </summary>
        public RedisProvider()
        {

        }


        private static ConnectionMultiplexer GetConnectionMultiplexer()
        {
            if (connectionMultiplexer == null)
            {
                lock (connectLock)
                {
                    if (connectionMultiplexer == null)
                    {
                        connectionMultiplexer = ConnectionMultiplexer.Connect(GetDefaultConnectionString());
                    }
                }
            }
            return connectionMultiplexer;
        }

        public IDatabase GetDatabase()
        {
            if (database == null)
            {
                lock (this)
                {
                    if (database == null)
                    {
                        database = GetConnectionMultiplexer().GetDatabase(GetDefaultDatabaseId());
                    }
                }
            }
            return database;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public ISubscriber GetSubscriber()
        {
            return GetConnectionMultiplexer().GetSubscriber();
        }

        private static string GetDefaultConnectionString()
        {
            var connStr = ConfigurationManager.ConnectionStrings[connectionKey];
            if (connStr == null || string.IsNullOrWhiteSpace(connStr.ConnectionString))
            {
                return "localhost";
            }
            return connStr.ConnectionString;
        }

        private static int GetDefaultDatabaseId()
        {
            var appSetting = ConfigurationManager.AppSettings[databaseIdKey];
            if (string.IsNullOrWhiteSpace(appSetting))
            {
                return -1;
            }

            int databaseId;
            if (!int.TryParse(appSetting, out databaseId))
            {
                return -1;
            }
            return databaseId;
        }

        public void Dispose()
        {
            lock (this)
            {
                database = null;
            }
        }
    }
}
